Abort a drag when a keynav drop has not destination
authorMatthias Clasen <mclasen@redhat.com>
Thu, 23 Dec 2010 02:46:23 +0000 (21:46 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 23 Dec 2010 02:47:14 +0000 (21:47 -0500)
This was claimed to cause problems for Chromium, see bug 599130.

Also work around apparent rounding errors in XIWarpDevice by
setting the 'small step' for keynav dnd to 2 instead of 1 - I notice
that a warp seems to sometimes warp a little less than I tell it to,
and if I tell it to only move by 1 pixel then moving less means
that you are stuck.

gtk/gtkdnd.c

index 8efbacd39f2602e115552627b06d4e6727df25a0..d0c230179811ca28c12508a2e5564f54fc365e72 100644 (file)
@@ -4184,7 +4184,7 @@ gtk_drag_motion_cb (GtkWidget      *widget,
  *************************************************************/
 
 #define BIG_STEP 20
-#define SMALL_STEP 1
+#define SMALL_STEP 2
 
 static gboolean
 gtk_drag_key_cb (GtkWidget         *widget, 
@@ -4204,41 +4204,49 @@ gtk_drag_key_cb (GtkWidget         *widget,
   if (event->type == GDK_KEY_PRESS)
     {
       switch (event->keyval)
-       {
-       case GDK_KEY_Escape:
-         gtk_drag_cancel (info, GTK_DRAG_RESULT_USER_CANCELLED, event->time);
-         return TRUE;
+{
+        case GDK_KEY_Escape:
+          gtk_drag_cancel (info, GTK_DRAG_RESULT_USER_CANCELLED, event->time);
+          return TRUE;
 
-       case GDK_KEY_space:
-       case GDK_KEY_Return:
+        case GDK_KEY_space:
+        case GDK_KEY_Return:
         case GDK_KEY_ISO_Enter:
-       case GDK_KEY_KP_Enter:
-       case GDK_KEY_KP_Space:
-         gtk_drag_end (info, event->time);
-         gtk_drag_drop (info, event->time);
-         return TRUE;
-
-       case GDK_KEY_Up:
-       case GDK_KEY_KP_Up:
-         dy = (state & GDK_MOD1_MASK) ? -BIG_STEP : -SMALL_STEP;
-         break;
-         
-       case GDK_KEY_Down:
-       case GDK_KEY_KP_Down:
-         dy = (state & GDK_MOD1_MASK) ? BIG_STEP : SMALL_STEP;
-         break;
-         
-       case GDK_KEY_Left:
-       case GDK_KEY_KP_Left:
-         dx = (state & GDK_MOD1_MASK) ? -BIG_STEP : -SMALL_STEP;
-         break;
-         
-       case GDK_KEY_Right:
-       case GDK_KEY_KP_Right:
-         dx = (state & GDK_MOD1_MASK) ? BIG_STEP : SMALL_STEP;
-         break;
-       }
-      
+        case GDK_KEY_KP_Enter:
+        case GDK_KEY_KP_Space:
+          if ((gdk_drag_context_get_selected_action (info->context) != 0) &&
+              (gdk_drag_context_get_dest_window (info->context) != NULL))
+            {
+              gtk_drag_end (info, event->time);
+              gtk_drag_drop (info, event->time);
+            }
+          else
+            {
+              gtk_drag_cancel (info, GTK_DRAG_RESULT_NO_TARGET, event->time);
+            }
+
+          return TRUE;
+
+        case GDK_KEY_Up:
+        case GDK_KEY_KP_Up:
+          dy = (state & GDK_MOD1_MASK) ? -BIG_STEP : -SMALL_STEP;
+          break;
+
+        case GDK_KEY_Down:
+        case GDK_KEY_KP_Down:
+          dy = (state & GDK_MOD1_MASK) ? BIG_STEP : SMALL_STEP;
+          break;
+
+        case GDK_KEY_Left:
+        case GDK_KEY_KP_Left:
+          dx = (state & GDK_MOD1_MASK) ? -BIG_STEP : -SMALL_STEP;
+          break;
+
+        case GDK_KEY_Right:
+        case GDK_KEY_KP_Right:
+          dx = (state & GDK_MOD1_MASK) ? BIG_STEP : SMALL_STEP;
+          break;
+        }
     }
 
   /* Now send a "motion" so that the modifier state is updated */